package cn.com.main;

import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;

public class CryptoExample {
    public static void main(String[] args) throws Exception {
        String plaintext = "Hello, worldHello, worldHello, worldHello, worldHello, worldHello, worldHello, worldHello, worldHello, world!";
        byte[] key = "MySecretKey12345".getBytes(); // 16字节的密钥

        // 加密
        byte[] encrypted = encrypt(plaintext.getBytes(), key);
        System.out.println("加密后的数据：" + new String(encrypted));

        // 解密
        byte[] decrypted = decrypt(encrypted, key);
        System.out.println("解密后的数据：" + new String(decrypted));
    }

    public static byte[] encrypt(byte[] plaintext, byte[] key) throws Exception {
        Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
        SecretKeySpec secretKey = new SecretKeySpec(key, "AES");
        cipher.init(Cipher.ENCRYPT_MODE, secretKey);

        // 分段加密
        byte[] encrypted = segmentEncrypt(cipher, plaintext);

        return encrypted;
    }

    public static byte[] decrypt(byte[] ciphertext, byte[] key) throws Exception {
        Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
        SecretKeySpec secretKey = new SecretKeySpec(key, "AES");
        cipher.init(Cipher.DECRYPT_MODE, secretKey);

        // 分段解密
        byte[] decrypted = segmentEncrypt(cipher, ciphertext);

        return decrypted;
    }

    // 分段加密方法
    private static byte[] segmentEncrypt(Cipher cipher, byte[] plaintext) throws Exception {
        int blockSize = cipher.getBlockSize(); // 获取加密算法的块大小
        byte[] encryptedData = new byte[0]; // 用于存储加密后的数据

        // 分段加密
        for (int i = 0; i < plaintext.length; i += blockSize) {
            int length = Math.min(blockSize, plaintext.length - i); // 计算当前块的长度
            byte[] block = new byte[length]; // 创建当前块的字节数组
            System.arraycopy(plaintext, i, block, 0, length); // 将明文数据复制到当前块中
            byte[] encryptedBlock = cipher.update(block); // 加密当前块
            encryptedData = concatenateArrays(encryptedData, encryptedBlock); // 将加密后的块添加到加密数据中
        }

        // 处理最后一个块
        byte[] finalBlock = cipher.doFinal();
        encryptedData = concatenateArrays(encryptedData, finalBlock);

        return encryptedData;
    }

    // 将两个字节数组连接起来
    private static byte[] concatenateArrays(byte[] array1, byte[] array2) {
        byte[] result = new byte[array1.length + array2.length];
        System.arraycopy(array1, 0, result, 0, array1.length);
        System.arraycopy(array2, 0, result, array1.length, array2.length);
        return result;
    }
}
